package cs343;

/**
* <p>
* Title: CS 343 Project: Pong
* </p>
* <p>
* Description: CS 343 Project  
* This class keeps track of the ball that is used in the game.
* It tracks the coordinates and checks if the ball is out of 
* bounds and if the ball collided with a paddle
* </p>
* 
* @author Jenny Windsperger, Stirling Pankow, Will Prew, Shane O'Malley-Potting
* @email jennifer.windsperger@my.uwrf.edu, stirling.pankow@my.uwrf.edu,
*        william.prew@my.uwrf.edu, shane.omalley-potting@my.uwrf.edu
* @date December 1st 2011
*/

public class Ball {
	
	//variables to track the ball
	private int xPosition;
	private int yPosition;
	private int radius;
	private int speed;
	private int heading;
	private int score = 0;
	private boolean collision = false;
	
	/**
	 * Constructor to initialize ball
	 */
	public Ball(int x, int y, int s, int r, int h){
		xPosition = x;
		yPosition = y;
		radius = r;
		speed = s;
		heading = h;		
	}
	
	/**
	 * method that moves the ball
	 * Postcondition: ball is moving
	 */
	public void moveAhead(int dist){
		//movement in the y coordinate
		yPosition += (int) (dist*Math.sin(Math.toRadians(heading)));
		//movement in the x coordinate
		xPosition += (int) (dist*Math.cos(Math.toRadians(heading)));
	}
	
	/**
	 * Method to check if the ball went out of bounds
	 * Postcondition: false if the ball went out of bounds
	 * 				  true if the ball is still in play
	 */
	public boolean outOfBounds(int arenaLength){
		if((xPosition - radius <= 0)|| (xPosition + radius >= arenaLength))
			return false;
		else
			return true;
	}
		
	/**
	 * Method to check of the ball has collided with a paddle or a wall
	 * Postcondition: if the ball collided, the ball will change direction
	 */
	public void checkCollision(int arenaHeight, int arenaLength, Paddle paddle){
		//if the ball collided with the paddle: execute
		if((xPosition - radius <= paddle.getPaddleWidth()) || (xPosition + radius >= arenaLength - paddle.getPaddleWidth()) ){
			if((yPosition > (paddle.getPaddlePosition() - paddle.getPaddleHeight()/2)) && ((yPosition < (paddle.getPaddlePosition() + paddle.getPaddleHeight()/2))) ){
				collision = true;
				//Checks which paddle the ball is colliding with and places the ball just outside it
				//Used to prevent re-matching collision parameters 
				if(heading > 270 || heading <90)
					xPosition = arenaLength - paddle.getPaddleWidth()-1-radius;
				else
					xPosition = paddle.getPaddleWidth() + 1 + radius;

				//check which direction the ball was traveling and bounce based on that direction				
				if(heading > 270){
					heading = 540 - heading;
					score += speed;
				}
				else if(heading < 90 && heading > 0){
					heading = 180 - heading;
					score += speed;
				}
				else if(heading > 90 && heading < 180)
					heading = 180 - heading;
				else if( heading >180 && heading < 270)
					heading = 540 - heading;
				
			}
		}
		else
			collision = false;
		
		//if the ball collided with the top of the arena: execute
		if(yPosition - radius <= 0) { 
			yPosition = radius + 1;
			heading = 360 - heading;
		}
		
		//if the ball collided with the bottom of the arena: execute
		if(yPosition >= arenaHeight -2*radius){
			yPosition =  arenaHeight -2*radius -1;
			heading = 360 - heading;
		}
	}
	
	//Getters and Setters
	public int getxPosition() {
		return xPosition;
	}

	public void setxPosition(int xPosition) {
		this.xPosition = xPosition;
	}

	public int getyPosition() {
		return yPosition;
	}

	public void setyPosition(int yPosition) {
		this.yPosition = yPosition;
	}

	public int getRadius() {
		return radius;
	}

	public void setRadius(int radius) {
		this.radius = radius;
	}

	public int getSpeed() {
		return speed;
	}

	public void setSpeed(int speed) {
		this.speed = speed;
	}

	public int getHeading() {
		return heading;
	}

	public void setHeading(int heading) {
		this.heading = heading;
	}

	public int getScore() {
		return score;
	}

	public void setScore(int score) {
		this.score = score;
	}

	public void setCollision(boolean collision) {
		this.collision = collision;
	}

	public boolean isCollision() {
		return collision;
	}
	
}
